package com.ssm.platform.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ssm.platform.pojo.param.UsersParam;
import com.ssm.platform.pojo.query.UsersQuery;
import com.ssm.platform.pojo.vo.UsersVo;
import com.ssm.platform.service.IUsersService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.validation.groups.Default;
import java.util.Set;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.springframework.http.ContentDisposition.attachment;

/**
 * @see Validated https://blog.csdn.net/f641385712/article/details/97621755
 */
@Validated(Default.class)
@RestController
@Tag(name = "用户")
@RequestMapping("users")
@RequiredArgsConstructor
public class UsersController {
    final IUsersService usersService;

    @Operation(summary = "新增用户")
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public UsersVo post(@Valid @RequestBody UsersParam param) {
        return usersService.post(param);
    }

    @DeleteMapping
    @Operation(summary = "删除用户")
    @PreAuthorize("hasRole('ADMIN')")
    public Boolean delete(@Parameter(name = "用户名集合") @Size(min = 1) @RequestParam("username") Set<@Valid @NotBlank String> usernames) {
        return usersService.delete(usernames);
    }

    @PutMapping
    @Operation(summary = "修改用户")
    public UsersVo put(@RequestBody UsersParam param) {
        return usersService.put(param);
    }

    @GetMapping
    @Operation(summary = "分页查询列表")
    public IPage<UsersVo> get(UsersQuery query) {
        return usersService.get(query);
    }

    /**
     * https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async-output-stream
     */
    @Operation(summary = "导出")
    @ResponseStatus(HttpStatus.CREATED)
    @GetMapping(path = "export", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<StreamingResponseBody> export(UsersQuery query, @Pattern(regexp = "[^.]+", message = "不能有后缀") String filename) {
        String fullFilename = filename + ".xlsx";
        return ResponseEntity.status(HttpStatus.CREATED)
                .contentType(MediaTypeFactory.getMediaType(fullFilename).orElse(MediaType.APPLICATION_OCTET_STREAM))
                .headers(h -> h.setContentDisposition(attachment().filename(fullFilename, UTF_8).build()))
                // .header(CONTENT_DISPOSITION, attachment().filename(fullFilename, UTF_8).build().toString())
                .body(body -> StreamUtils.copy(usersService.export(query), body));
    }

    @GetMapping("{username}")
    @Operation(summary = "查询单个用户(根据用户名，REST 风格)")
    public Object get(@Parameter(name = "用户名", example = "zhangsan") @PathVariable @NotEmpty String username) {
        return username;
    }

    @GetMapping("info")
    @Operation(summary = "当前登录用户信息")
    public Object info(@AuthenticationPrincipal User user, Authentication authentication) {
        return authentication;
    }
}